<form #generatorForm="ngForm" class="generator-form">

    <div class="page-header">
        <h2><fa-icon [icon]="'rocket'"></fa-icon>&nbsp;<span>应用生成</span></h2>
    </div>

    <div class="container generator-container">
        <div class="card">
            <div class="card-header">
                <h4>项目配置</h4>
            </div>
            <div class="card-body">
        <jhi-git-provider-alert *ngIf="isAuthenticated()" [tab]="'generate-application'"></jhi-git-provider-alert>
        <jhi-git-provider *ngIf="isAuthenticated()" (sharedData)="updateSharedData($event)" [simpleMode]="true"></jhi-git-provider>
        <ng-content select="[generator-header]"></ng-content>
        <div class="row">
            <div class="col-md-8">
                <div class="form-group">
                    <label for="baseName">应用名称</label>
                    <input type="text" class="form-control" id="baseName" [(ngModel)]="model.baseName" name="baseName"
                           #baseName="ngModel" required pattern="^([a-zA-Z0-9]*)$">
                    <div *ngIf="baseName.errors" class="alert alert-danger">您的应用名称不能包含特殊字符或空格。</div>
                </div>
            </div>
        </div>
        <div class="row" *ngIf="!config.hideRepositoryName">
            <div class="col-md-8">
                <div class="form-group">
                    <label for="repositoryName">仓库名称</label>
                    <input type="text" class="form-control" id="repositoryName" [(ngModel)]="repositoryName" name="repositoryName"
                           required pattern="^([a-zA-Z0-9\-_]*)$">
                </div>
            </div>
        </div>
            </div>
        </div>
        
        <ng-container *ngIf="!config.hideApplicationType">
            <div class="card mt-4">
                <div class="card-header">
                    <h4>应用类型</h4>
                </div>
                <div class="card-body">
            <div class="row">
                <div class="col-md-8">
                    <div class="form-group">
                        <label for="applicationType">您想创建哪种类型的应用？</label>
                        <select id="applicationType" [(ngModel)]="model.applicationType" name="applicationType"
                                class="form-control" #applicationType="ngModel"
                                (change)="changeApplicationType()">
                            <option value="monolith">单体应用（推荐用于简单项目）</option>
                            <option value="microservice">微服务应用</option>
                            <option value="gateway">微服务网关</option>
                        </select>
                    </div>
                </div>
            </div>
                </div>
            </div>
        </ng-container>
        
        <div class="card mt-4">
            <div class="card-header">
                <h4>服务端选项</h4>
            </div>
            <div class="card-body">
        <div class="row">
            <div class="col-md-8">
                <div class="form-group">
                    <label for="packageName">您的默认 Java 包名是什么？</label>
                    <input type="text" class="form-control" id="packageName" [(ngModel)]="model.packageName"
                           name="packageName" #packageName="ngModel"
                           required pattern="^([a-z_]{1}[a-z0-9_]*(\.[a-z_]{1}[a-z0-9_]*)*)$"
                           (change)="changePackageName()">
                    <div *ngIf="packageName.errors" class="alert alert-danger">您提供的包名不是有效的 Java 包名。</div>
                </div>
                <div class="form-group">
                    <label for="serverPort">您希望服务器在哪个端口上运行？它应该是唯一的以避免端口冲突。</label>
                    <input type="number" class="form-control" id="serverPort" [(ngModel)]="model.serverPort"
                           name="serverPort" #serverPort="ngModel"
                           required>
                </div>
                <!-- <div class="form-group" *ngIf="!config.hideServiceDiscoveryType" [hidden]="model.applicationType === 'monolith'">
                    <label for="serviceDiscoveryType">您想使用 Consul 作为服务注册中心吗？</label>
                    <select id="serviceDiscoveryType" [(ngModel)]="model.serviceDiscoveryType"
                            name="serviceDiscoveryType"
                            class="form-control"
                            #serviceDiscoveryType="ngModel" (change)="changeServiceDiscoveryType()">
                        <option value="consul">是</option>
                        <option value="false">否</option>
                        <option value="eureka">使用 JHipster Registry（已弃用）</option>
                    </select>
                </div> -->
                <div class="form-group" *ngIf="!config.hideAuthenticationType">
                    <label for="authenticationType">您想使用哪种<i>类型</i>的认证？</label>
                    <select id="authenticationType" [(ngModel)]="model.authenticationType" name="authenticationType"
                            class="form-control" #authenticationType="ngModel" (change)="changeAuthenticationType()">
                        <option value="jwt">JWT 认证（无状态，使用令牌）</option>
                        <option value="oauth2">OAuth 2.0 / OIDC 认证（有状态，适用于 Keycloak 和 Okta）</option>
                        <option value="session" *ngIf="model.serviceDiscoveryType !== 'eureka' && model.applicationType === 'monolith'">HTTP 会话认证（有状态，Spring Security 默认机制）
                        </option>
                    </select>
                </div>
                <div class="form-group" *ngIf="!config.hideDatabaseType">
                    <label for="databaseType">您想使用哪种<i>类型</i>的数据库？</label>
                    <select id="databaseType" [(ngModel)]="model.databaseType" name="databaseType" class="form-control"
                            #databaseType="ngModel" (change)="changeDatabaseType()">
                        <option value="sql" *ngIf="!isDatabaseTypeOptionHidden('sql')">SQL（H2、MySQL、MariaDB、PostgreSQL、Oracle、MSSQL）</option>
                        <option value="mongodb" *ngIf="!isDatabaseTypeOptionHidden('mongodb')">MongoDB</option>
                        <option value="cassandra" *ngIf="model.authenticationType !== 'oauth2' && !isDatabaseTypeOptionHidden('cassandra')">Cassandra</option>
                        <option value="couchbase" *ngIf="!isDatabaseTypeOptionHidden('couchbase')">Couchbase</option>
                        <option value="neo4j" *ngIf="!isDatabaseTypeOptionHidden('neo4j')">Neo4j</option>
                        <option value="no" *ngIf="!isDatabaseTypeOptionHidden('no')">无数据库</option>
                    </select>
                </div>
                <div class="form-group" *ngIf="!config.hideProdDatabaseType">
                    <label for="prodDatabaseType">您想使用哪种<i>生产环境</i>数据库？</label>
                    <select id="prodDatabaseType" [(ngModel)]="model.prodDatabaseType" name="prodDatabaseType"
                            class="form-control" #prodDatabaseType="ngModel" (change)="changeProdDatabaseType()">
                        <option value="mysql" *ngIf="!isProdDatabaseOptionHidden('sql', 'mysql')">MySQL</option>
                        <option value="postgresql" *ngIf="!isProdDatabaseOptionHidden('sql', 'postgresql')">PostgreSQL</option>
                        <option value="mariadb" *ngIf="!isProdDatabaseOptionHidden('sql', 'mariadb')">MariaDB</option>
                        <option value="oracle" *ngIf="!isProdDatabaseOptionHidden('sql', 'oracle')">Oracle（请遵循我们的文档使用 Oracle 专有驱动程序）
                        </option>
                        <option value="mssql" *ngIf="!isProdDatabaseOptionHidden('sql', 'mssql')">Microsoft SQL Server</option>
                        <option value="mongodb" *ngIf="!isProdDatabaseOptionHidden('mongodb', 'mongodb')">MongoDB</option>
                        <option value="cassandra" *ngIf="!isProdDatabaseOptionHidden('cassandra', 'cassandra')">Cassandra</option>
                        <option value="couchbase" *ngIf="!isProdDatabaseOptionHidden('couchbase', 'couchbase')">Couchbase</option>
                        <option value="neo4j" *ngIf="!isProdDatabaseOptionHidden('neo4j', 'neo4j')">Neo4j</option>
                        <option value="no" [hidden]="config.disableNoDatabaseOptions == true" *ngIf="!isProdDatabaseOptionHidden('no', 'no') || !config.hideDatabaseType">无数据库</option>
                    </select>
                </div>
              <div class="form-group" *ngIf="config.hideIaCTool">
                <label for="iaCTools">您想使用基础设施即代码工具吗（多选）？</label>
                <select id="iaCTools" [(ngModel)]="model.iaCTools" name="iaCTools" class="form-control"
                        #iaCTools="ngModel" multiple>
                  <option *ngFor="let option of iaCToolOptions" [value]="option.value">{{option.name}}</option>
                </select>
              </div>
                <div class="form-group" *ngIf="!config.hideDevDatabaseType">
                    <label for="devDatabaseType">您想使用哪种<i>开发环境</i>数据库？</label>
                    <select id="devDatabaseType" [(ngModel)]="model.devDatabaseType" name="devDatabaseType"
                            class="form-control" #devDatabaseType="ngModel">
                        <option value="h2Disk" *ngIf="!isDevDatabaseOptionHidden('sql', 'h2Disk')">基于磁盘持久化的 H2</option>
                        <option value="h2Memory" *ngIf="!isDevDatabaseOptionHidden('sql', 'h2Memory')">基于内存持久化的 H2</option>
                        <option value="mysql" *ngIf="!isDevDatabaseOptionHidden('sql', 'mysql')">MySQL</option>
                        <option value="mariadb" *ngIf="!isDevDatabaseOptionHidden('sql', 'mariadb')">MariaDB</option>
                        <option value="postgresql" *ngIf="!isDevDatabaseOptionHidden('sql', 'postgresql')">PostgreSQL</option>
                        <option value="oracle" *ngIf="!isDevDatabaseOptionHidden('sql', 'oracle')">Oracle（请遵循我们的文档使用 Oracle 专有驱动程序）
                        </option>
                        <option value="mssql" *ngIf="!isDevDatabaseOptionHidden('sql', 'mssql')">Microsoft SQL Server</option>
                        <option value="mongodb" *ngIf="!isDevDatabaseOptionHidden('mongodb', 'mongodb')">MongoDB</option>
                        <option value="cassandra" *ngIf="!isDevDatabaseOptionHidden('cassandra', 'cassandra')">Cassandra</option>
                        <option value="couchbase" *ngIf="!isDevDatabaseOptionHidden('couchbase', 'couchbase')">Couchbase</option>
                        <option value="neo4j" *ngIf="!isDevDatabaseOptionHidden('neo4j', 'neo4j')">Neo4j</option>
                        <option value="no" [hidden]="config.disableNoDatabaseOptions == false" *ngIf="!isDevDatabaseOptionHidden('no', 'no') || !config.hideDatabaseType">无数据库</option>
                    </select>
                </div>
                <div class="form-group" *ngIf="!config.hideCacheProvider">
                    <label for="cacheProvider">您想使用 Spring 缓存抽象吗？</label>
                    <select id="cacheProvider" [(ngModel)]="model.cacheProvider" name="cacheProvider"
                            class="form-control" #cacheProvider="ngModel">
                        <option value="ehcache">是，使用 ehcache（本地缓存，适用于单节点）</option>
                        <option value="caffeine">是，使用 Caffeine（本地缓存，适用于单节点）</option>
                        <option value="hazelcast">是，使用 HazelCast（分布式缓存，适用于多节点）</option>
                        <option value="infinispan">是，使用 Infinispan（混合缓存，适用于多节点）</option>
                        <option value="memcached">是，使用 Memcached（分布式缓存）</option>
                        <option value="redis">是，使用 Redis（单服务器）</option>
                        <option value="no">否</option>
                    </select>
                </div>
                <div class="form-group" [hidden]="model.databaseType !== 'sql' || model.cacheProvider === 'no'" *ngIf="!config.hideHibernateCache">
                    <label for="enableHibernateCache">您想使用 Hibernate 二级缓存吗？</label>
                    <select id="enableHibernateCache" [(ngModel)]="model.enableHibernateCache" name="enableHibernateCache"
                            class="form-control" #enableHibernateCache="ngModel">

                        <option [ngValue]="true">是</option>
                        <option [ngValue]="false">否</option>
                    </select>
                </div>
                <div class="form-group" *ngIf="!config.hideBuildTool">
                    <label for="buildTool">您想使用 Maven 还是 Gradle 来构建后端？</label>
                    <select id="buildTool" [(ngModel)]="model.buildTool" name="buildTool" class="form-control"
                            #buildTool="ngModel">
                        <option value="maven">Maven</option>
                        <option value="gradle">Gradle</option>
                    </select>
                </div>
                <div class="form-group" *ngIf="!config.hideOtherComponents">
                    <label>您还想使用哪些其他技术？</label>
                    <div class="container">
                        <div class="row">
                            <div class="col-md-1">
                                <input type="checkbox" class="form-control" id="enableSwaggerCodegen"
                                       [(ngModel)]="model.enableSwaggerCodegen" name="enableSwaggerCodegen"
                                       #enableSwaggerCodegen="ngModel">
                            </div>
                            <div class="col-md-5">
                                <label for="enableSwaggerCodegen">使用 OpenAPI-generator 进行 API 优先开发</label>
                            </div>
                            <div class="col-md-1">
                                <input type="checkbox" class="form-control" id="searchEngine"
                                       [(ngModel)]="model.searchEngine" name="searchEngine"
                                       #searchEngine="ngModel"
                                       [hidden]="model.databaseType === 'cassandra' || model.databaseType === 'couchbase'">
                            </div>
                            <div class="col-md-5">
                                <label for="searchEngine"
                                       [hidden]="model.databaseType === 'cassandra' || model.databaseType === 'couchbase'">使用 Elasticsearch 的搜索引擎</label>
                            </div>

                        </div>
                        <div class="row">
                            <div class="col-md-1">
                                <input type="checkbox" class="form-control" id="websocket" [(ngModel)]="model.websocket"
                                       name="websocket"
                                       #websocket="ngModel">
                            </div>
                            <div class="col-md-5">
                                <label for="websocket">使用 Spring Websocket 的 WebSockets</label>
                            </div>
                            <div class="col-md-1">
                                <input type="checkbox" class="form-control" id="messageBroker"
                                       [(ngModel)]="model.messageBroker" name="messageBroker"
                                       #messageBroker="ngModel">
                            </div>
                            <div class="col-md-5">
                                <label for="messageBroker">使用 Apache Kafka 的异步消息</label>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
            </div>
        </div>
        
        <ng-container *ngIf="!config.hideClientSideOptions && model.applicationType !== 'microservice'">
            <div class="card mt-4">
                <div class="card-header">
                    <h4>客户端选项</h4>
                </div>
                <div class="card-body">
            <div class="row">
                <div class="col-md-8">
                    <div class="form-group">
                        <label for="clientFramework">您想为客户端使用哪种<i>框架</i>？</label>
                        <select id="clientFramework" [(ngModel)]="model.clientFramework" name="clientFramework"
                                class="form-control" #clientFramework="ngModel">
                            <option value="angularX">Angular</option>
                            <option value="react">React</option>
                            <option value="vue">Vue</option>
                        </select>
                    </div>
                </div>
                <div class="col-md-12">
                    <div class="form-group">
                        <label for="withAdminUi">您想生成管理界面吗？</label>
                        <select id="withAdminUi" [(ngModel)]="model.withAdminUi" name="withAdminUi"
                                class="form-control" #withAdminUi="ngModel">
                            <option [ngValue]="true">是</option>
                            <option [ngValue]="false">否</option>
                        </select>
                    </div>
                </div>
            </div>
                </div>
            </div>
        </ng-container>
        
        <!-- <ng-container *ngIf="!config.hideI18nOptions">
            <div class="card mt-4">
                <div class="card-header">
                    <h4>国际化选项</h4>
                </div>
                <div class="card-body">
            <div class="row">
                <div class="col-md-8">
                    <div class="form-group">
                        <label for="enableTranslation">您想启用国际化支持吗？</label>
                        <select id="enableTranslation" [(ngModel)]="model.enableTranslation" name="enableTranslation"
                                class="form-control" #enableTranslation="ngModel">
                            <option [ngValue]="true">是</option>
                            <option [ngValue]="false">否</option>
                        </select>
                    </div>
                    <div class="form-group" [hidden]="model.enableTranslation === false">
                        <label for="nativeLanguage">请选择应用的本地语言</label>
                        <select id="nativeLanguage" [(ngModel)]="model.nativeLanguage" name="nativeLanguage"
                                class="form-control" #nativeLanguage="ngModel">
                            <option *ngFor="let option of languageOptions" [value]="option.value">{{option.name}}</option>
                        </select>
                    </div>
                    <div class="form-group" [hidden]="model.enableTranslation === false">
                        <label for="languages">请选择要安装的其他语言</label>
                        <select id="languages" [(ngModel)]="model.languages" name="languages" class="form-control"
                                #languages="ngModel" multiple>
                            <option *ngFor="let option of languageOptions" [value]="option.value">{{option.name}}</option>
                        </select>
                    </div>
                </div>
            </div>
                </div>
            </div>
        </ng-container> -->
        
        <ng-container *ngIf="!config.hideTestingOptions">
            <div class="card mt-4">
                <div class="card-header">
                    <h4>测试选项</h4>
                </div>
                <div class="card-body">
            <div class="row">
                <div class="col-md-8">
                    <div class="form-group">
                        <label for="testFrameworks">除了 JUnit 和 Jest 外，您还想使用哪些测试框架？</label>
                        <select id="testFrameworks" [(ngModel)]="model.testFrameworks" name="testFrameworks"
                                class="form-control" #testFrameworks="ngModel"
                                multiple>
                            <option value="gatling">Gatling</option>
                            <option value="cucumber">Cucumber</option>
                            <option value="cypress" *ngIf="model.applicationType !== 'microservice'">Cypress</option>
                            <!-- <option value="protractor" *ngIf="model.applicationType !== 'microservice'">Protractor（已弃用）</option> -->
                        </select>
                    </div>
                </div>
            </div>
                </div>
            </div>
        </ng-container>
        <ng-content select="[generator-footer]"></ng-content>
        
        <div class="row mt-4">
            <div class="col-md-8">
                <div class="action-buttons text-center">
                    <p></p>
                    <div [ngSwitch]="!submitted">
                        <div *ngSwitchCase="true">
                            <button type="submit" class="btn btn-primary btn-lg" [disabled]="!generatorForm.form.valid" (click)="onSubmit()" *ngIf="selectedGitProvider">
                                在 {{selectedGitProvider}} 上生成
                            </button>
                            <button type="submit" class="btn btn-info btn-lg" [disabled]="!generatorForm.form.valid" (click)="onSubmitDownload()">
                                下载为 Zip 文件
                            </button>
                            <button type="button" class="btn btn-dark btn-lg" (click)="newGenerator()">重置</button>
                        </div>
                        <div *ngSwitchCase="false">
                            <fa-icon [icon]="'sync'" [spin]="true"></fa-icon>
                            <button type="submit" class="btn btn-primary btn-lg" [disabled]="true" *ngIf="selectedGitProvider">
                                在 {{selectedGitProvider}} 上生成
                            </button>
                            <button type="submit" class="btn btn-info btn-lg" [disabled]="true">
                                下载为 Zip 文件
                            </button>
                        </div>
                    </div>
                    <div *ngIf="!generatorForm.form.valid" class="alert alert-danger mt-3">"生成"按钮被禁用，因为表单中存在错误。</div>
                </div>
            </div>
        </div>
    </div>
</form>

<style>
    .generator-form {
        margin-bottom: 30px;
    }
    
    .page-header {
        margin-bottom: 20px;
        padding: 15px 0;
        border-bottom: 1px solid #e7e7e7;
    }
    
    .generator-container {
        padding: 0;
    }
    
    .card {
        border-radius: 8px;
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        margin-bottom: 20px;
        border: none;
    }
    
    .card-header {
        background-color: #3e8acc;
        color: white;
        border-top-left-radius: 8px;
        border-top-right-radius: 8px;
        padding: 12px 20px;
    }
    
    .card-header h4 {
        margin: 0;
        font-weight: 500;
    }
    
    .card-body {
        padding: 20px;
        background-color: #fff;
    }
    
    .form-group {
        margin-bottom: 20px;
    }
    
    .form-group label {
        font-weight: 500;
        margin-bottom: 8px;
        display: block;
    }
    
    .form-control {
        border-radius: 4px;
        border: 1px solid #ddd;
        padding: 8px 12px;
        height: auto;
    }
    
    .form-control:focus {
        border-color: #3e8acc;
        box-shadow: 0 0 0 0.2rem rgba(62, 138, 204, 0.25);
    }
    
    .btn-primary, .btn-info, .btn-dark {
        border-radius: 4px;
        padding: 10px 20px;
        font-weight: 500;
        transition: all 0.3s ease;
        margin: 0 5px;
    }
    
    .btn-primary {
        background-color: #3e8acc;
        border-color: #3e8acc;
    }
    
    .btn-primary:hover {
        background-color: #3579b5;
        border-color: #3579b5;
    }
    
    .action-buttons {
        margin-top: 20px;
        margin-bottom: 20px;
    }
    
    .alert-danger {
        border-radius: 4px;
        margin-top: 8px;
    }
</style>
